package work.igames.vertxcreate.handler;

import cn.hutool.core.annotation.AnnotationUtil;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.ReflectUtil;
import io.vertx.codegen.annotations.Nullable;
import io.vertx.core.AsyncResult;
import io.vertx.core.Handler;
import io.vertx.core.MultiMap;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.RoutingContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import work.igames.vertxcreate.annotation.JsonBody;
import work.igames.vertxcreate.annotation.Parameter;
import work.igames.vertxcreate.common.CommonParam;
import work.igames.vertxcreate.constant.StateEnum;
import work.igames.vertxcreate.service.UserSkillAsyncService;
import work.igames.vertxcreate.utils.HttpUtil;

import java.lang.reflect.Method;

/**
 * @ClassName UserSkillHandler
 * @Description
 * @Author Jingxiao.Ye
 * @Date 2020/10/30 下午5:00
 * @Version V1.0
 * @Since JDK 11
 */
@Component
public class UserSkillHandler {

    @Autowired
    private UserSkillAsyncService userSkillAsyncService;

    /**
    * @Description: 所有加@Paramter注解的注入，所有加JsonBody的注入，handler注入
    * @Param: 
    * @return: 
    * @Author: Jingxiao.Ye
    * @Date: 2020/11/2
    */
    public void dispatch(String methodName, RoutingContext routingContext) {
        CommonParam param = getParam(routingContext);
        MultiMap multiMap = param.getMultiMap();
        JsonObject jsonObject = param.getJsonObject();
        Method method = ReflectUtil.getMethodByName(userSkillAsyncService.getClass(), methodName);
        java.lang.reflect.Parameter[] parameters = method.getParameters();
        Object[] args = new Object[parameters.length];
        int index = 0;
        for (java.lang.reflect.Parameter parameter : parameters) {
            Object o = null;
            if(parameter.getType().isAssignableFrom(Handler.class)){
                o = resultHandler(routingContext);
            }
            Parameter parameterAnnotation = parameter.getDeclaredAnnotation(Parameter.class);
            if(parameterAnnotation != null){
                String name = parameterAnnotation.value();
                if("".equals(parameterAnnotation.value())){
                    //通过name查找
                    name = parameter.getName();
                }
                o = multiMap.get(name);
            }else {
                JsonBody jsonBodyAnnotation = parameter.getDeclaredAnnotation(JsonBody.class);
                if(jsonBodyAnnotation != null){
                    o = jsonObject.mapTo(parameter.getType());
                }
            }
            args[index] = o;
            index ++;
        }
        //从param中寻找
        ReflectUtil.invoke(userSkillAsyncService, methodName, args);
    }

    public CommonParam getParam(RoutingContext routingContext){
        HttpServerRequest request = routingContext.request();
        MultiMap multiMap = request.params();
        JsonObject bodyAsJson = routingContext.getBodyAsJson();
        return new CommonParam().setMultiMap(multiMap).setJsonObject(bodyAsJson);
    }

    public <T> Handler<AsyncResult<T>> resultHandler(RoutingContext routingContext) {
        return ar -> {
            if (ar.succeeded()) {
                HttpUtil.writeCommonJsonResponse(routingContext, ar.result(), StateEnum.SUCCESS);
            } else {
                HttpUtil.writeCommonJsonResponse(routingContext, null, StateEnum.FAIL);
            }
        };
    }
}
